import React, { useEffect, useRef, useState, useCallback } from "react";
import { NextPage } from "next";
import dayjs from "dayjs";
import hljs from "highlight.js";
import Helmet from "react-helmet";

import style from "./index.module.scss";
import { ArticleApi } from "@/api/article";
import { Modal, Input, message, Icon } from "antd";
import Router from "next/router";
import Link from "next/link";
import { Recommend } from "@/components/Recommend";
import { Comment } from "@/components/Comment";

let higIninted;
const Article: NextPage = (props) => {
  let { setting = {}, article } = props as any;
  const ref = useRef(null);
  const [password, setPassword] = useState("");
  const [needPass, setneedPass] = useState(false);

  // 检查密码是否正确
  const checkPass = useCallback(() => {
    ArticleApi.checkPassword(article.id, password).then((res) => {
      if (res.pass) {
        article = Object.assign(article, res);
        setneedPass(false);
      } else {
        message.warn("密码输入错误");
        setneedPass(true);
      }
    });
  }, [article.id, password]);

  // 设置是否需要密码
  useEffect(() => {
    setneedPass(article && article.needPassword);
  }, [article.id]);

  // 更新文章阅读量
  useEffect(() => {
    ArticleApi.updateArticleViews(article.id);
  }, [needPass, article.id]);
  // 高亮
  useEffect(() => {
    if (!higIninted) {
      hljs.initHighlightingOnLoad();
      higIninted = true;
    }
    const blocks = ref.current.querySelectorAll("pre code");
    blocks.forEach((block) => hljs.highlightBlock(block));
  }, [article.id, needPass]);
  return (
    <div className={"container"}>
      <Helmet>
        <meta
          name="keywords"
          content={
            article.tags.map((t) => t.label).join(",") + article.category?.label
          }
        />
        <meta name="description" content={article?.summary} />
        <title>{`${article?.title}|${setting?.systemTitle}`}</title>
      </Helmet>
      <div className={style.wrapper}>
        <div className={style.head}>
          <div className={style.cover}>
            <img src={article?.cover} />
          </div>
          <h2 className={style.title}>{article.title}</h2>
          <p className={style.time}>
            发布与{dayjs(article.publishAt).format("YYYY-MM-DD hh:mm:ss")}
            {"  ★  "}
            阅读量{article.views}
          </p>
        </div>
        <div ref={ref} className={style.content}>
          <div
            className={"markdown"}
            dangerouslySetInnerHTML={{
              __html: article.content,
            }}
          ></div>
          <div className={style.footerInfo}>
            <blockquote>
              <p>
                发布时间：
                {dayjs(article?.publishAt).format("YYYY-MM-DD hh:mm:ss")}
              </p>
            </blockquote>
            <div className={style.tags}>
              {article?.tags?.map((t) => (
                <Link
                  key={t.value}
                  href={"/tags/[tag]"}
                  as={`/tags/${t.value}`}
                >
                  <a key={t.value} className={style.tag}>
                    <Icon type="tags" />
                    <span>{t.label}</span>
                  </a>
                </Link>
              ))}
            </div>
          </div>
          {article?.isCommentable && (
            <Comment hostId={article?.id} isInHostPage={false} />
          )}
        </div>
        <div className={style.recommend}>
          <p>推荐阅读</p>
          <Recommend articleId={article?.id} mode="card" asCard={false} />
        </div>
      </div>
      <Modal
        title={"输入文章密码"}
        visible={needPass}
        cancelText="取消"
        okText={"确认"}
        onOk={checkPass}
        onCancel={() => Router.back()}
      >
        <Input
          value={password}
          onChange={(e) => {
            setPassword(e.target.value);
          }}
        />
      </Modal>
    </div>
  );
};

Article.getInitialProps = async (ctx) => {
  const { id } = ctx.query;
  const article = await ArticleApi.getArticle(id);
  return { article };
};

export default Article;
